//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include "Application.hpp"
#include <chrono>


namespace Application
{
	//
	enum class ClockState : uint32_t
	{
		kPaused		=	0,
		kRunning,
		kStepping
	};

	class APPLICATION_EXPORT Clock
	{
	public:
		//
		typedef std::chrono::high_resolution_clock::time_point		TimePoint_t;
		typedef std::chrono::high_resolution_clock::duration		Duration_t;
		typedef std::chrono::high_resolution_clock					Clock_t;

		//
		Clock( ClockState state=ClockState::kRunning );

		//
		void				Update();

		void				State( const ClockState state );
		ClockState			State() const;

		void				Scale( float scale );
		float				Scale() const;

		void				StepRate( float rate );
		float				StepRate() const;

		void				MaxStep( float maxStep );
		float				MaxStep() const;

		void				Reset();

		uint64_t			Frame();
		float				DeltaTime() const;
		float				ElapsedTime() const;

		TimePoint_t			Now() const;

	private:
		void				_Delta( const TimePoint_t& now, Duration_t& real, Duration_t& adj ) const;
		void				_CurrentDelta( TimePoint_t& current, Duration_t& delta ) const;

		//
		ClockState			mState;
		TimePoint_t			mStartTime;
		TimePoint_t			mCurrentTime;
		Duration_t			mDelta;
		Duration_t			mStepRate;
		Duration_t			mMaxStep;
		float				mScale;
		uint64_t			mFrame;
	};
}
